import org.junit.Test;

import java.util.List;

import static org.junit.Assert.assertEquals;

/**
 * StringSearch HW08 Tests
 * I make no guarantee that my test cases cover all of the cases
 * that will be tested by the TAs.
 * 
 * You rely upon these test cases at your own risk.  I cannot be held
 * responsible for incorrect tests.
 * @author Jonathan Jemson
 *
 */
public class StringSearchTestJJ
{
	/**
	 * If your KMP suffix table starts with 0, set to true.
	 * If it starts with -1, set to false.
	 */
	private static final boolean KMP_STARTS_WITH_ZERO = false;
	@Test
	public void testBoyerMoore()
	{
		String text1 = "helloworldmynameisworldphone";
		String pattern1 = "world";
		List<Integer> ind = StringSearch.boyerMoore(pattern1, text1);
		assertEquals(2, ind.size());
		assertEquals(new Integer(5), ind.get(0));
		assertEquals(new Integer(18), ind.get(1));
	}
	@Test
	public void testBoyerMoore2()
	{
		String text2 = "aaxaxaaaxaxaaaxax";
		String pattern2 = "aaxax";
		List<Integer> ind2 = StringSearch.boyerMoore(pattern2, text2);
		assertEquals(3, ind2.size());
		assertEquals(new Integer(0), ind2.get(0));
		assertEquals(new Integer(6), ind2.get(1));
		assertEquals(new Integer(12), ind2.get(2));
	}
	@Test
	public void testBoyerMoore3()
	{
		String text2 = "aaaaa";
		String pattern2 = "a";
		List<Integer> ind2 = StringSearch.boyerMoore(pattern2, text2);
		assertEquals(5, ind2.size());
		assertEquals(new Integer(0), ind2.get(0));
		assertEquals(new Integer(1), ind2.get(1));
		assertEquals(new Integer(2), ind2.get(2));
		assertEquals(new Integer(3), ind2.get(3));
		assertEquals(new Integer(4), ind2.get(4));
	}
	@Test
	public void testBoyerMoore4()
	{
		String text4 = "crush kkyle with aardvarks";
		String pattern4 = "aardvark";
		List<Integer> ind4 = StringSearch.boyerMoore(pattern4, text4);
		assertEquals(1, ind4.size());
		assertEquals(new Integer(17), ind4.get(0));
	}
	@Test
	public void testBoyerMoore5()
	{
		String text5 = "aaaaabb";
		String pattern5 = "aaa";
		List<Integer> ind = StringSearch.boyerMoore(pattern5, text5);
		assertEquals(3, ind.size());
		assertEquals(new Integer(0), ind.get(0));
		assertEquals(new Integer(1), ind.get(1));
		assertEquals(new Integer(2), ind.get(2));
	}
	@Test
	public void testBoyerMoore6()
	{
		String text6 = "world";
		String pattern6 = "loremipsumdolorworldsitamet";
		List<Integer> ind = StringSearch.boyerMoore(pattern6, text6);
		assertEquals(0, ind.size());
	}
	@Test
	public void testBuildBoyerMooreCharTable()
	{
		String needle = "aardvark";
		int[] m = StringSearch.buildBoyerMooreCharTable(needle);
		for (int i = Character.MIN_VALUE; i < Character.MAX_VALUE; i++)
		{
			if (i == 'a')
				assertEquals(2, m[i]);
			else if (i == 'r')
				assertEquals(1, m[i]);
			else if (i == 'd')
				assertEquals(4, m[i]);
			else if (i == 'v')
				assertEquals(3, m[i]);
			else if (i == 'k')
				assertEquals(1, m[i]);
			else
				assertEquals(8, m[i]);
		}
	}
	
	@Test
	public void testKmp()
	{
		String myText = "helloworldmynameisworldphone";
		String pattern = "world";
		List<Integer> ind = StringSearch.kmp(pattern, myText);
		assertEquals(2, ind.size());
		assertEquals(new Integer(5), ind.get(0));
		assertEquals(new Integer(18), ind.get(1));
	}
	@Test
	public void testKmp2()
	{
		String text2 = "aaxaxaaaxaxaaaxax";
		String pattern2 = "aaxax";
		List<Integer> ind2 = StringSearch.kmp(pattern2, text2);
		assertEquals(3, ind2.size());
		assertEquals(new Integer(0), ind2.get(0));
		assertEquals(new Integer(6), ind2.get(1));
		assertEquals(new Integer(12), ind2.get(2));
	}
	@Test
	public void testKmp3()
	{
		String text2 = "aaaaa";
		String pattern2 = "a";
		List<Integer> ind2 = StringSearch.kmp(pattern2, text2);
		assertEquals(5, ind2.size());
		assertEquals(new Integer(0), ind2.get(0));
		assertEquals(new Integer(1), ind2.get(1));
		assertEquals(new Integer(2), ind2.get(2));
		assertEquals(new Integer(3), ind2.get(3));
		assertEquals(new Integer(4), ind2.get(4));
	}
	@Test
	public void testKmp4()
	{
		String text4 = "crush kkyle with aardvarks";
		String pattern4 = "aardvark";
		List<Integer> ind4 = StringSearch.kmp(pattern4, text4);
		assertEquals(1, ind4.size());
		assertEquals(new Integer(17), ind4.get(0));
	}
	@Test
	public void testKmp5()
	{
		String text5 = "aaaaabb";
		String pattern5 = "aaa";
		List<Integer> ind = StringSearch.kmp(pattern5, text5);
		assertEquals(3, ind.size());
		assertEquals(new Integer(0), ind.get(0));
		assertEquals(new Integer(1), ind.get(1));
		assertEquals(new Integer(2), ind.get(2));
	}
	@Test
	public void testKmp6()
	{
		String text6 = "world";
		String pattern6 = "loremipsumdolorworldsitamet";
		List<Integer> ind = StringSearch.kmp(pattern6, text6);
		assertEquals(0, ind.size());
	}
	/**
	 * This tests the suffix table the way you set it above (boolean)
	 * I make no promises about testing the TA way.
	 */
	@Test
	public void testBuildKmpSuffixTable()
	{
		String needle = "abcdabcabe";
		int[] f = StringSearch.buildKmpSuffixTable(needle);
		if (KMP_STARTS_WITH_ZERO)  // Professor's technique
		{
			assertEquals(0, f[0]);
			for (int i = 1; i < 4; i++)
			{
				assertEquals(0, f[i]);
			}
			assertEquals(1, f[4]);
			assertEquals(2, f[5]);
			assertEquals(3, f[6]);
			assertEquals(1, f[7]);
			assertEquals(2, f[8]);
			assertEquals(0, f[9]);
		}
		else //TA's technique
		{
			assertEquals(-1, f[0]);
			for (int i = 0; i < 5; i++)
			{
				assertEquals(0, f[i]);
			}
			assertEquals(1, f[5]);
			assertEquals(2, f[6]);
			assertEquals(3, f[7]);
			assertEquals(1, f[8]);
			assertEquals(2, f[9]);
		}
	}
	
	@Test
	public void testRabinKarp()
	{
		String myText = "helloworldmynameisworldphone";
		String pattern = "world";
		List<Integer> ind = StringSearch.rabinKarp(pattern, myText);
		assertEquals(2, ind.size());
		assertEquals(new Integer(5), ind.get(0));
		assertEquals(new Integer(18), ind.get(1));
	}
	@Test
	public void testRabinKarp2()
	{
		String text2 = "aaxaxaaaxaxaaaxax";
		String pattern2 = "aaxax";
		List<Integer> ind2 = StringSearch.rabinKarp(pattern2, text2);
		assertEquals(3, ind2.size());
		assertEquals(new Integer(0), ind2.get(0));
		assertEquals(new Integer(6), ind2.get(1));
		assertEquals(new Integer(12), ind2.get(2));
	}
	@Test
	public void testRabinKarp3()
	{
		String text2 = "aaaaa";
		String pattern2 = "a";
		List<Integer> ind2 = StringSearch.rabinKarp(pattern2, text2);
		assertEquals(5, ind2.size());
		assertEquals(new Integer(0), ind2.get(0));
		assertEquals(new Integer(1), ind2.get(1));
		assertEquals(new Integer(2), ind2.get(2));
		assertEquals(new Integer(3), ind2.get(3));
		assertEquals(new Integer(4), ind2.get(4));
	}
	@Test
	public void testRabinKarp4()
	{
		String text4 = "crush kkyle with aardvarks";
		String pattern4 = "aardvark";
		List<Integer> ind4 = StringSearch.rabinKarp(pattern4, text4);
		assertEquals(1, ind4.size());
		assertEquals(new Integer(17), ind4.get(0));
	}
	@Test
	public void testRabinKarp5()
	{
		String text5 = "aaaaabb";
		String pattern5 = "aaa";
		List<Integer> ind = StringSearch.rabinKarp(pattern5, text5);
		assertEquals(3, ind.size());
		assertEquals(new Integer(0), ind.get(0));
		assertEquals(new Integer(1), ind.get(1));
		assertEquals(new Integer(2), ind.get(2));
	}
	@Test
	public void testRabinKarp6()
	{
		String text6 = "world";
		String pattern6 = "loremipsumdolorworldsitamet";
		List<Integer> ind = StringSearch.rabinKarp(pattern6, text6);
		assertEquals(0, ind.size());
	}
	@Test
	public void testRabinKarpTrivial()
	{
		String myText = "xhi";
		String pattern = "hi";
		List<Integer> ind = StringSearch.rabinKarp(pattern, myText);
		assertEquals(1, ind.size());
		assertEquals(new Integer(1), ind.get(0));
	}

	@Test
	public void testHashString()
	{
		assertEquals(65, StringSearch.hashString("A"));
		assertEquals(64871, StringSearch.hashString("AB"));
	}
	@Test
	public void testUpdateHash()
	{
		assertEquals(65, StringSearch.hashString("A"));
		assertEquals(66, StringSearch.updateHash(65, 'B', 'A', 1));
	}

}
